package com.zym.framework.form;

import com.alibaba.fastjson.JSONObject;
import com.zym.application.exception.AppBugExcepiton;
import com.zym.application.model.ReturnModel;
import com.zym.application.session.Http;
import com.zym.application.session.HttpCall;
import com.zym.application.utils.LogUtils;
import com.zym.application.utils.StringUtils;
import com.zym.framework.constants.color;
import com.zym.framework.notice.NoticeUtils;
import com.zym.framework.utlis.AppUtlis;
import com.zym.framework.utlis.FromUtils;
import com.zym.framework.utlis.FxmlUtil;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * QQ 165149324
 * 臧英明
 *
 * @author
 * @create 2021-02-05
 */
public class ZymForm  implements FxForm{
    private String submitUrl;
    private String getUrl;
    private String xmlPath;
    private FormCallback formCallback;
    private FXMLLoader fxmlLoader;
    private String title;
    private List<Field> fields = new ArrayList<>();
    private Object controller;
    private Button save;
    private Stage winView;
    private JSONObject bean = new JSONObject();
    public ZymForm(String submitUrl,String getUrl,String xmlPath,String title){
        this.getUrl = getUrl;
        this.submitUrl=submitUrl;
        if(StringUtils.isEmpty(xmlPath)){
            throw new AppBugExcepiton("XML配置不正常");
        }
        this.xmlPath = xmlPath;
        init(title);
    }
    public void beanPut(String key,Object value){

    }

    public void show(){
        winView.show();
    }
    public void setFormCallback(FormCallback formCallback) {
        this.formCallback = formCallback;
    }


    private void init(String title){
        FXMLLoader fxmlLoader = FxmlUtil.loadFxmlFromResource(xmlPath);
         this.controller = fxmlLoader.getController();
        if(controller == null){
            throw new AppBugExcepiton("controller 未配置");
        }
        //扫描注解
        scanField(controller);
        //初始化窗口
        initView(title,fxmlLoader.getRoot());
    }

    private void initView(String title,Parent root) {
        winView = AppUtlis.getFromWinView(title, root);
        //获取
        List<Button> list = getFromDefaultButoon();
        Scene scene = winView.getScene();
        Parent sp = scene.getRoot();
        if(sp instanceof SplitPane){
            SplitPane splitPane = (SplitPane) sp;
            //创建底部工具栏
            ToolBar toolBar = new ToolBar();
            toolBar.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
            ObservableList<Node> items = toolBar.getItems();
            for (int i = list.size()-1; i >=0; i--) {
                items.add(list.get(i));
            }
            splitPane.getItems().add(toolBar);
        }

    }

    public <T> T getController(Class<T> clazz) {
        return (T)controller;
    }

    private  List<Button> getFromDefaultButoon() {
        List<Button> buttons = new ArrayList<>();
        save=new Button();
        save.setText("保存");
        save.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
               submit();
            }
        });
        Button cancel = new Button();
        cancel.setText("取消");
        cancel.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                close();
            }
        });
        buttons.add(save);
        buttons.add(cancel);
        return buttons;
    }

    private void scanField(Object controller){
        Field[] declaredFields = controller.getClass().getDeclaredFields();
        for (int i = 0; i <declaredFields.length ; i++) {
            Field field = declaredFields[i];
            ZymField annotation = field.getAnnotation(ZymField.class);
            if(annotation !=null){ //说明是对象字段
                fields.add(field);
            }
        }
    }


    public void reset(){
        clearError();
        clearFieid();
        bean.clear();
    }

    @Override
    public void submit() {
        clearError();
        JSONObject fieldData = FromUtils.getFieldData(fields,controller);
        bean.putAll(fieldData);
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("jsonBean",bean);
        if(formCallback != null){
            formCallback.submitStart(jsonObject);
        }
        LogUtils.println(jsonObject.toJSONString());
        Http.post(submitUrl, jsonObject,winView, new HttpCall() {
            @Override
            public void exe(ReturnModel post) {
                if(post.isValid()){
                    JSONObject objToJSONObject = post.getObjToJSONObject();
                    addError(objToJSONObject);
                }
                if (post.isSuceess()){
                    NoticeUtils.success(post.ObjToString());
                    close();
                    if(formCallback != null){
                        formCallback.submitEnd();
                    }
                }
                if (post.isFailed()){
                    NoticeUtils.error(post.ObjToString());
                }
            }
        });
    }
    public void clearFieid(){
        FromUtils.clearFieid(fields, controller);
    }

    @Override
    public void clearError() {
        if(fields.size() >0){
            FromUtils.clearError(fields.get(0), controller);
        }

    }

    private void addError(Map map){
        for (int i = 0; i < fields.size(); i++) {
            Field field = fields.get(i);
            Node fieidNode = FromUtils.getFieidNode(field, controller);
            String id = fieidNode.getId();
            if(map.containsKey(id)){
                Label label = new Label();
                label.setText(map.get(id).toString());
                label.setId("#_Error"+ fieidNode.getId());
                fieidNode.setStyle("-fx-border-color: "+ color.ERROR_COLOR+"; -fx-border-width: 1;");
                label.setStyle("-fx-text-fill: "+ color.ERROR_COLOR+";");
                label.setLayoutX(fieidNode.getLayoutX()+2);
                double height = fieidNode.getLayoutBounds().getHeight();
                label.setLayoutY(fieidNode.getLayoutY()+height);
                Parent parent1 = fieidNode.getParent();
                if(parent1 instanceof Pane){
                    Pane parent = (Pane) parent1;
                    parent.getChildren().add(label);
                }
            }
        }

    }
    @Override
    public void open(String id) {
        reset();
        if(StringUtils.isNotEmpty(id)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",id);
            Http.post(getUrl, jsonObject, new HttpCall() {
                @Override
                public void exe(ReturnModel post) {
                    Map data = (Map) post.getObj();
                    //添加数据中
                    if(formCallback != null){
                        formCallback.getStart(data);
                    }
                    bean.putAll(data);
                    FromUtils.addFieldData(data,fields,controller);
                }
            });
        }
        winView.show();
    }


    @Override
    public void close() {
        winView.hide();
    }

    public void lockSaveButton(boolean b) {
        save.setDisable(b);
    }

    public void openForCode(String code,String url) {
        reset();
        if(StringUtils.isNotEmpty(code)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",code);
            Http.post(url, jsonObject, new HttpCall() {
                @Override
                public void exe(ReturnModel post) {
                    Map data = (Map) post.getObj();
                    //添加数据中
                    if(formCallback != null){
                        formCallback.getStart(data);
                    }
                    bean.putAll(data);
                    FromUtils.addFieldData(data,fields,controller);
                }
            });
        }
        winView.show();
    }

    public void setBean(JSONObject bean) {
        this.bean = bean;
    }
}
